package operations

import (
	"encoding/json"
	"github.com/sirupsen/logrus"
	"mydocker/common"
	"mydocker/container"
	"os"
	"path"
	"strconv"
	"syscall"
)

// StopContainer 停止容器，修改容器状态
func StopContainer(containerID string) {
	// 1.根据容器 ID 查询容器信息
	info, err := getInfoByContainerID(containerID)
	if err != nil {
		logrus.Errorf("getContainerInfo error : %v", err)
		return
	}
	pidInt, err := strconv.Atoi(info.Pid)
	if err != nil {
		logrus.Errorf("Conver pid from string to int error %v", err)
		return
	}
	// 2.发送 SIGTERM 信号，杀死进程。
	// syscall.SIGTERM 是终止信号，这是一个温和的信号，用于请求进程自行终止，接收到该信号的进程会捕获该信号，并执行清理工作（关闭文件描述符、释放资源等），然后退出
	// syscall.SIGTERM 是一个常用的信号，用于实现进程的优雅关闭和资源的清理。
	if err = syscall.Kill(pidInt, syscall.SIGTERM); err != nil {
		logrus.Errorf("stop container, pid: %d, err : %v", pidInt, err)
		return
	}
	// 3.修改容器状态，将容器置为 STOP 状态，并清空 PID
	info.Status = common.Stop
	info.Pid = ""
	newContent, err := json.Marshal(info)
	if err != nil {
		logrus.Errorf("Json marshal %s error %v", containerID, err)
		return
	}
	// 4.重新写回存储容器信息的文件
	configFilePath := path.Join(common.DefaultContainerInfoPath, containerID, common.ConfigName)
	err = os.WriteFile(configFilePath, newContent, common.Perm0622)
	if err != nil {
		logrus.Errorf("Write file %s error:%v", configFilePath, err)
	}
}

func getInfoByContainerID(containerID string) (*container.ContainerInfo, error) {
	dirPath := path.Join(common.DefaultContainerInfoPath, containerID)
	configFilePath := path.Join(dirPath, common.ConfigName)
	content, err := os.ReadFile(configFilePath)
	if err != nil {
		logrus.Errorf("read config file error : %v", err)
		return nil, err
	}
	info := new(container.ContainerInfo)
	if err = json.Unmarshal(content, info); err != nil {
		return nil, err
	}
	return info, nil
}
